|
|
@@ -11,11 +11,11 @@ module Agents
|
11
|
11
|
description <<-MD
|
12
|
12
|
The Jira Agent subscribes to Jira issue updates.
|
13
|
13
|
|
14
|
|
- `jira_url` specidies the full URL of the jira installation, including https://
|
|
14
|
+ `jira_url` specifies the full URL of the jira installation, including https://
|
15
|
15
|
`jql` is an optional Jira Query Language-based filter to limit the flow of events. See [JQL Docs](https://confluence.atlassian.com/display/JIRA/Advanced+Searching) for details.
|
16
|
16
|
`username` and `password` are optional, and may need to be specified if your Jira instance is read-protected
|
17
|
17
|
|
18
|
|
- The agent does periodical queries and emits the events containing the updated issues in JSON format.
|
|
18
|
+ The agent does periodic queries and emits the events containing the updated issues in JSON format.
|
19
|
19
|
NOTE: upon the first execution, the agent will fetch everything available by the JQL query. So if it's not desirable, limit the `jql` query by date.
|
20
|
20
|
MD
|
21
|
21
|
|
|
|
@@ -40,16 +40,18 @@ module Agents
|
40
|
40
|
'username' => '',
|
41
|
41
|
'password' => '',
|
42
|
42
|
'jira_url' => 'https://jira.atlassian.com',
|
43
|
|
- 'jql' => ''
|
|
43
|
+ 'jql' => '',
|
|
44
|
+ 'expected_update_period_in_days', '7'
|
44
|
45
|
}
|
45
|
46
|
end
|
46
|
47
|
|
47
|
48
|
def validate_options
|
48
|
|
- errors.add(:base, "you need to specify your jira URL") unless options['jira_url'].present?
|
|
49
|
+ errors.add(:base, "you need to specify your jira URL") unless options['jira_url'].present?
|
|
50
|
+ errors.add(:base, "you need to specify the expected update period") unless options['expected_update_period_in_days'].present?
|
49
|
51
|
end
|
50
|
52
|
|
51
|
53
|
def working?
|
52
|
|
- (events_count.present? && events_count > 0)
|
|
54
|
+ event_created_within?(options['expected_update_period_in_days']) && !recent_error_logs?
|
53
|
55
|
end
|
54
|
56
|
|
55
|
57
|
def check
|
|
|
@@ -57,23 +59,19 @@ module Agents
|
57
|
59
|
|
58
|
60
|
current_run = Time.now.utc.iso8601
|
59
|
61
|
last_run = Time.parse(memory[:last_run]) if memory[:last_run]
|
60
|
|
- begin
|
61
|
|
- issues = get_issues(last_run)
|
|
62
|
+ issues = get_issues(last_run)
|
62
|
63
|
|
63
|
|
- issues.each do |issue|
|
64
|
|
- updated = Time.parse(issue['fields']['updated'])
|
|
64
|
+ issues.each do |issue|
|
|
65
|
+ updated = Time.parse(issue['fields']['updated'])
|
65
|
66
|
|
66
|
|
- # this check is more precise than in get_issues()
|
67
|
|
- # see get_issues() for explanation
|
68
|
|
- if updated > last_run then
|
69
|
|
- create_event :payload => issue
|
70
|
|
- end
|
|
67
|
+ # this check is more precise than in get_issues()
|
|
68
|
+ # see get_issues() for explanation
|
|
69
|
+ if updated > last_run
|
|
70
|
+ create_event :payload => issue
|
71
|
71
|
end
|
72
|
|
-
|
73
|
|
- memory[:last_run] = current_run
|
74
|
|
- rescue Exception => e
|
75
|
|
- log(e.message)
|
76
|
72
|
end
|
|
73
|
+
|
|
74
|
+ memory[:last_run] = current_run
|
77
|
75
|
end
|
78
|
76
|
|
79
|
77
|
private
|
|
|
@@ -84,7 +82,7 @@ module Agents
|
84
|
82
|
def request_options
|
85
|
83
|
ropts = {:headers => {"User-Agent" => "Huginn (https://github.com/cantino/huginn)"}}
|
86
|
84
|
|
87
|
|
- if !options[:username].empty? then
|
|
85
|
+ if !options[:username].empty?
|
88
|
86
|
ropts = ropts.merge({:basic_auth => {:username =>options[:username], :password=>options[:password]}})
|
89
|
87
|
end
|
90
|
88
|
|
|
|
@@ -105,7 +103,7 @@ module Agents
|
105
|
103
|
|
106
|
104
|
jql = ""
|
107
|
105
|
|
108
|
|
- if !options[:jql].empty? && since then
|
|
106
|
+ if !options[:jql].empty? && since
|
109
|
107
|
jql = "(#{options[:jql]}) and updated >= '#{since.strftime('%Y-%m-%d %H:%M')}'"
|
110
|
108
|
else
|
111
|
109
|
jql = options[:jql] if !options[:jql].empty?
|
|
|
@@ -116,11 +114,11 @@ module Agents
|
116
|
114
|
loop do
|
117
|
115
|
response = HTTParty.get(request_url(jql, startAt), request_options)
|
118
|
116
|
|
119
|
|
- if response.code == 400 then
|
|
117
|
+ if response.code == 400
|
120
|
118
|
raise RuntimeError.new("Jira error: #{response['errorMessages']}")
|
121
|
|
- elsif response.code == 403 then
|
|
119
|
+ elsif response.code == 403
|
122
|
120
|
raise RuntimeError.new("Authentication failed: Forbidden (403)")
|
123
|
|
- elsif response.code != 200 then
|
|
121
|
+ elsif response.code != 200
|
124
|
122
|
raise RuntimeError.new("Request failed: #{response}")
|
125
|
123
|
end
|
126
|
124
|
|